
#include "stdafx.h"
//#include "resource.h"
#include <Exdisp.h>
#include <comutil.h>
#include "WebBrowserAxDialog.h"
#include "Exdispid.h" // platform SDK header


// IUnknown methods
HRESULT __stdcall DWebBrowserEventsImpl::QueryInterface(REFIID riid, LPVOID* ppv)
{
	*ppv = NULL;
	
	if (IID_IUnknown == riid || __uuidof(SHDocVw::DWebBrowserEventsPtr) == riid)
	{
		*ppv = (LPUNKNOWN)(SHDocVw::DWebBrowserEventsPtr*)this;
		AddRef();
		return NOERROR;
	}
	else if (IID_IOleClientSite == riid)
	{
		*ppv = (IOleClientSite*)this;
		AddRef();
		return NOERROR;
	}
	else if (IID_IDispatch == riid)
	{
		*ppv = (IDispatch*)this;
		AddRef();
		return NOERROR;
	}
	else
	{
		return E_NOTIMPL;
	}
}

ULONG __stdcall DWebBrowserEventsImpl::AddRef()
{
	return 1;
}
ULONG __stdcall DWebBrowserEventsImpl::Release()
{
	return 0;
}

// IDispatch methods
HRESULT __stdcall DWebBrowserEventsImpl::GetTypeInfoCount(UINT* pctinfo)
{
	UNREFERENCED_PARAMETER(pctinfo);
	return E_NOTIMPL;
}

HRESULT __stdcall DWebBrowserEventsImpl::GetTypeInfo(UINT iTInfo,
                                                     LCID lcid,
                                                     ITypeInfo** ppTInfo)
{
	UNREFERENCED_PARAMETER(iTInfo);
	UNREFERENCED_PARAMETER(lcid);
	UNREFERENCED_PARAMETER(ppTInfo);
	return E_NOTIMPL;
}

HRESULT __stdcall DWebBrowserEventsImpl::GetIDsOfNames(REFIID riid,
                                                       LPOLESTR* rgszNames,
                                                       UINT cNames,
                                                       LCID lcid,
                                                       DISPID* rgDispId)
{
	UNREFERENCED_PARAMETER(riid);
	UNREFERENCED_PARAMETER(rgszNames);
	UNREFERENCED_PARAMETER(cNames);
	UNREFERENCED_PARAMETER(lcid);
	UNREFERENCED_PARAMETER(rgDispId);
	return E_NOTIMPL;
}

HRESULT __stdcall DWebBrowserEventsImpl::Invoke(DISPID dispIdMember,
                                                REFIID riid,
                                                LCID lcid,
                                                WORD wFlags,
                                                DISPPARAMS __RPC_FAR *pDispParams,
                                                VARIANT __RPC_FAR *pVarResult,
                                                EXCEPINFO __RPC_FAR *pExcepInfo,
                                                UINT __RPC_FAR *puArgErr)
{
	UNREFERENCED_PARAMETER(puArgErr);
	UNREFERENCED_PARAMETER(pExcepInfo);
	UNREFERENCED_PARAMETER(pVarResult);
	UNREFERENCED_PARAMETER(wFlags);
	UNREFERENCED_PARAMETER(lcid);
	UNREFERENCED_PARAMETER(riid);
	
	HRESULT res = NOERROR;
	
	/*
	#ifdef _DEBUG
	  {
	    WCHAR b[128];
	    wsprintf(b, L"%i\r\n", dispIdMember);
	    OutputDebugString(b);
	  }
	#endif
	*/
	
	switch (dispIdMember)
	{
		case DISPID_NEWWINDOW:
		{
			if (pDispParams->rgvarg[0].pboolVal)
				*pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE;
				
			m_cpParent->HandleNewWindow(pDispParams->rgvarg[5].bstrVal);
		}
		break;
		
		case DISPID_BEFORENAVIGATE:
		{
			VARIANT_BOOL bCancel = VARIANT_FALSE;
			BeforeNavigate(_bstr_t(pDispParams->rgvarg[5].bstrVal),
			               0,
			               pDispParams->rgvarg[3].bstrVal,
			               pDispParams->rgvarg[2].pvarVal,
			               pDispParams->rgvarg[1].bstrVal,
			               pDispParams->rgvarg[0].pboolVal);
			               
			if (bCancel == VARIANT_TRUE)
				res = E_INVALIDARG;
				
		}
		break;
		
		case DISPID_NAVIGATECOMPLETE:
		{
			NavigateComplete(_bstr_t(pDispParams->rgvarg[0].bstrVal));
		}
		break;
		
		case DISPID_PROGRESSCHANGE:
			//ProgressChange(pDispParams->rgvarg[1].intVal, pDispParams->rgvarg[0].intVal);
			break;
			
		case DISPID_STATUSTEXTCHANGE:
			StatusTextChange(pDispParams->rgvarg[0].bstrVal);
			break;
			
		case DISPID_TITLECHANGE:
			TitleChange(pDispParams->rgvarg[0].bstrVal);
			break;
			
		case DISPID_COMMANDSTATECHANGE:
			CommandStateChange(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].boolVal);
			break;
			
		case DISPID_DOWNLOADBEGIN:
			DownloadBegin();
			break;
			
		case DISPID_DOWNLOADCOMPLETE:
			DownloadComplete();
			break;
			
		case DISPID_DOCUMENTCOMPLETE:
			//if (m_pWBDisp == pDispParams->rgvarg[1].pdispVal)
		{
			// If the LPDISPATCH are same, that means
			// it is the final DocumentComplete. Reset m_pWBDisp.
			
			//m_pWBDisp = NULL;
			
			m_cpParent->OnDocumentComplete();
		}
		break;
		
		/*
		case DISPID_TITLEICONCHANGE:
		{
		  int y = 0;
		}
		break;
		*/
	}
	
	return res;
}

std::wstring CWebBrowserAxDialog::ExtractDomain(LPCWSTR pszAddress)
{
	std::wstring strDomain;
	// Extract domain from addess.
	// For example: http://mail.yandex.ru/ -> yandex.ru
	LPCWSTR start = wcsstr(pszAddress, L"://");
	if (!start)
		start = wcsstr(pszAddress, L":\\\\");
		
	if (start)
	{
		start += 3;
		LPCWSTR end = wcsstr(start, L"/");
		if (!end)
			end = wcsstr(start, L"\\");
		if (!end)
			strDomain = start;
		else
			strDomain.assign(start, end - start);
	}
	
	return strDomain;
}


// Methods:
HRESULT DWebBrowserEventsImpl::BeforeNavigate(
    _bstr_t URL,
    long Flags,
    _bstr_t TargetFrameName,
    VARIANT * PostData,
    _bstr_t Headers,
    VARIANT_BOOL * Cancel)
{
	UNREFERENCED_PARAMETER(Flags);
	
	if (_wcsnicmp(URL, L"magnet:", 7) == 0)
	{
		if (Cancel)
			*Cancel = VARIANT_TRUE;
			
		m_cpParent->OnMagnet(URL);
	}
	else //if (Cancel && m_cpParent->GetFilterDomain().size() != 0)
	{
		if (m_cpParent->IsFiltered(URL))
		{
			*Cancel = VARIANT_TRUE;
		}
		else
		{
			*Cancel = VARIANT_FALSE;
		}
	}
	
	LPSTR pszPOSTData = NULL;
	int iPOSTDataLen = 0;
	
	if (PostData && PostData->vt == (VT_ARRAY | VT_UI1))
	{
		pszPOSTData = (CHAR*)PostData->parray->pvData;
		iPOSTDataLen = PostData->parray->rgsabound[0].cElements;
	}
	
	m_cpParent->OnBeforeNavigate(URL, Headers, pszPOSTData, iPOSTDataLen);
	
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::NavigateComplete(_bstr_t URL)
{
	/* example code
	SHDocVw::IWebBrowserAppPtr pWebBrowser = NULL;
	HRESULT hr = m_cpParent->GetDlgControl(IDC_EXPLORER1,
	__uuidof(SHDocVw::IWebBrowserAppPtr),
	(void**)&pWebBrowser);
	
	// get the html document
	MSHTML::IHTMLDocument2Ptr doc( pWebBrowser->Document );
	MSHTML::IHTMLElementPtr htmlbody( doc->body );
	
	BSTR content = NULL;
	htmlbody->get_innerHTML(&content);
	_bstr_t bcontent(content);
	*/
	
	m_cpParent->OnNavigateComplete();
	m_cpParent->OnDocumentComplete();
	
	return S_OK;
}
HRESULT DWebBrowserEventsImpl::StatusTextChange(_bstr_t Text)
{
	m_cpParent->Status().SetText(0, Text, 0);
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::ProgressChange(
    long Progress,
    long ProgressMax)
{
	UNREFERENCED_PARAMETER(Progress);
	UNREFERENCED_PARAMETER(ProgressMax);
	/*
	if (Progress == -1 || ProgressMax == 0)
	{
	  m_cpParent->Status().SetText(NULL, 0, 0);
	}
	else
	{
	  WCHAR wcPercent[10];
	  _itow_s(Progress * 100 / ProgressMax, wcPercent, _countof(wcPercent), 10);
	
	  m_cpParent->Status().SetText(wcPercent, 0, 0);
	}
	*/
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::DownloadComplete()
{
	m_cpParent->OnDownloadComplete();
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::CommandStateChange(
    long Command,
    VARIANT_BOOL Enable)
{
	m_cpParent->OnCommandStateChange(Command, Enable == VARIANT_TRUE);
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::DownloadBegin()
{
	m_cpParent->OnDownloadBegin();
	return S_OK;
}
HRESULT DWebBrowserEventsImpl::NewWindow(
    _bstr_t URL,
    long Flags,
    _bstr_t TargetFrameName,
    VARIANT * PostData,
    _bstr_t Headers,
    VARIANT_BOOL * Processed)
{
	UNREFERENCED_PARAMETER(URL);
	UNREFERENCED_PARAMETER(Flags);
	UNREFERENCED_PARAMETER(TargetFrameName);
	UNREFERENCED_PARAMETER(PostData);
	UNREFERENCED_PARAMETER(Headers);
	UNREFERENCED_PARAMETER(Processed);
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::TitleChange(_bstr_t Text)
{
	m_cpParent->OnTitleChange(Text);
	return S_OK;
}
HRESULT DWebBrowserEventsImpl::FrameBeforeNavigate(
    _bstr_t URL,
    long Flags,
    _bstr_t TargetFrameName,
    VARIANT * PostData,
    _bstr_t Headers,
    VARIANT_BOOL * Cancel)
{
	UNREFERENCED_PARAMETER(URL);
	UNREFERENCED_PARAMETER(Flags);
	UNREFERENCED_PARAMETER(TargetFrameName);
	UNREFERENCED_PARAMETER(PostData);
	UNREFERENCED_PARAMETER(Headers);
	UNREFERENCED_PARAMETER(Cancel);
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::FrameNavigateComplete(
    _bstr_t URL)
{
	UNREFERENCED_PARAMETER(URL);
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::FrameNewWindow(
    _bstr_t URL,
    long Flags,
    _bstr_t TargetFrameName,
    VARIANT * PostData,
    _bstr_t Headers,
    VARIANT_BOOL * Processed)
{
	UNREFERENCED_PARAMETER(URL);
	UNREFERENCED_PARAMETER(Flags);
	UNREFERENCED_PARAMETER(TargetFrameName);
	UNREFERENCED_PARAMETER(PostData);
	UNREFERENCED_PARAMETER(Headers);
	UNREFERENCED_PARAMETER(Processed);
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::Quit(VARIANT_BOOL * Cancel)
{
	UNREFERENCED_PARAMETER(Cancel);
	return S_OK;
}

HRESULT DWebBrowserEventsImpl::WindowMove()
{
	return S_OK;
}
HRESULT DWebBrowserEventsImpl::WindowResize()
{
	return S_OK;
}
HRESULT DWebBrowserEventsImpl::WindowActivate()
{
	return S_OK;
}
HRESULT DWebBrowserEventsImpl::PropertyChange(_bstr_t Property)
{
	UNREFERENCED_PARAMETER(Property);
	return S_OK;
}